#pragma once
#include "Hand.h"
#include <math.h>
//#include "DirectXFramework.h"

#define PI 3.14159265

Hand::Hand()
{
	high = 0;
	for(int i = 0; i < 5; ++i)
	{
		firstCardPair[i] = false;
		secondCardPair[i] = false;
	}
}

Hand::~Hand()
{
}

void Hand::Deal()
{
}

bool Hand::CardSpin(int s, float a)
{
	// this function will return a bool of whether or not it spun to the max scale

	if(slot[s].faceup)
	{
		slot[s].scale += a;
		if(slot[s].scale > 0.7f)
		{
			slot[s].scale = 0.7f;
			return true;
		}

		if(slot[s].scale < 0)
		{
			slot[s].scale = 0;
			CardFlip(s);
		}
	}
	else if(!slot[s].faceup)
	{
		slot[s].scale -= a;
		if(slot[s].scale > 0.7f)
		{
			slot[s].scale = 0.7f;
			return true;
		}
		if(slot[s].scale < 0)
		{
			slot[s].scale = 0;
			CardFlip(s);
		}
	}

	return false;
}

bool Hand::CardMove(int s, float spd, D3DXVECTOR3 dest)
{
	// this function will return a bool of whether or not it reached it's goal

	// if it's close enough, then it'll snap into position
	if(sqrt(pow((slot[s].position.x - dest.x), 2) + pow((slot[s].position.y - dest.y), 2)) <= 100.0f)
	{
		slot[s].position = dest;
		return true;
	}

	// get the slope and get the angle
	float x = slot[s].position.x - dest.x;
	float y = slot[s].position.y - dest.y;

	float angle = atan(y/x);

	//if(y >= 0 && x < 0)
	//	angle += PI;
	//else if(y < 0 && x < 0)
	//	angle -= PI;
	//else if(y > 0 && x == 0)
	//	angle = PI;
	//else if(y < 0 && x == 0)
	//	angle = -1 * PI;

	// move card based on slope and speed
	D3DXVECTOR3 newPos(spd * cos(angle), spd * sin(angle), 0.0f);
	slot[s].position.x += newPos.x;
	slot[s].position.y += newPos.y;

	// check if it reach it's destination
	if(slot[s].position == dest)
		return true;

	return false;
}

bool Hand::CardSlide(int s, float spd, D3DXVECTOR3 dest)
{
	// this function will return a bool of whether or not it reached it's goal

	// if it's close enough, then it'll snap into position
	if(slot[s].position.x - dest.x <= 100.0f)
	{
		slot[s].position.x = dest.x;
		return true;
	}

	// move the card horizontally
	if(slot[s].position.x < dest.x)
		slot[s].position.x += spd;
	else if(slot[s].position.x > dest.x)
		slot[s].position.x -= spd;
	else
		return true;

	// check if it reach it's destination
	if(slot[s].position.x == dest.x)
		return true;

	return false;
}

void Hand::SelectCard(int s)
{
	int count = 0;

	//count how many cards are selected
	for (int i=0; i < 5; i++)
	{
		if (select[i] == true)
			count++;
	}

	//if it's already selected, then deselect it
	if (select[s])
	{
		select[s] = false;
		slot[s].position.y += 32;
	}

	//if there are less than 2 cards selected, then it'll select it if it is not
	else if (!select[s] && count < 5)
	{
		select[s] = true;
		slot[s].position.y -= 32;
	}
}

void Hand::SetCard(int i, int v, short su, bool f, float r, float s, D3DCOLOR c)
{
	slot[i].rotation = r;
	slot[i].scale = s;
	slot[i].color = c;
	slot[i].value = v;
	slot[i].suit = su;
	slot[i].faceup = f;
}

void Hand::SetCard2(int i, Card card, bool f, float r, float s, D3DCOLOR c)
{
	// use this function instead of SetCard if you want to keep the values and cards consistent with the deck's list

	slot[i].rotation = r;
	slot[i].scale = s;
	slot[i].color = c;
	slot[i].value = card.value;
	slot[i].suit = card.suit;
	slot[i].faceup = f;
}

void Hand::RigHand(int a, int b, int c, int d, int e, short A, short B, short C, short D, short E)
{
	slot[0].value = a;
	slot[1].value = b;
	slot[2].value = c;
	slot[3].value = d;
	slot[4].value = e;

	slot[0].suit = A;
	slot[1].suit = B;
	slot[2].suit = C;
	slot[3].suit = D;
	slot[4].suit = E;
}

int Hand::HighCard()
{
	return high;
}

void Hand::OrganizeHand()
{
	Card temp[5];

	for(int i = 0; i < 5; ++i)
	{
		for(int j = 0; j < 5; j++)
		{
			if((i != j) && slot[i].value <= slot[j].value)
			{
				temp[i] = slot[i];
				slot[i] = slot[j];
				slot[j] = temp[i];

				temp[i].position.x = slot[i].position.x;
				slot[i].position.x = slot[j].position.x;
				slot[j].position.x = temp[i].position.x;
			}
		}
	}
	// insert code that sets x values to be relates to position im the list

}

void Hand::OrganizeHand2()
{
	// This does the exact same thing as OrgainizeHand() except it changes the destination instead of position

	Card temp[5];

	for(int i = 0; i < 5; ++i)
	{
		for(int j = 0; j < 5; j++)
		{
			if((i != j) && slot[i].value <= slot[j].value)
			{
				temp[i] = slot[i];
				slot[i] = slot[j];
				slot[j] = temp[i];

				temp[i].destination.x = slot[i].position.x;
				slot[i].destination.x = slot[j].position.x;
				slot[j].destination.x = temp[i].destination.x;
			}
		}
	}
	// insert code that sets x values to be relates to position im the list

}

void Hand::CardFlip(int s)
{
	//if it's faced up, then make it face down
	if (slot[s].faceup)
	{
		slot[s].faceup = false;
	}

	//if it's faced down, then make it face up
	else
	{
		slot[s].faceup = true;
	}
}

void Hand::CompThink()
{
	LPCWSTR comHand = this->Check();

	if(comHand == L"ROYAL FLUSH!" || comHand == L"Strait Flush" || comHand == L"Strait" || comHand == L"Flush" || comHand == L"Full House")
		return;


	
	if(comHand == L"One Pair" || comHand == L"Three of a Kind" || comHand == L"Two Pair")
	{
		for(int i = 0; i < 5; i++)
		{
			if(!firstCardPair[i] && !secondCardPair[i])
			{
				select[i] = true;
			}
		}
		return;
	}


	if(comHand == L"Junk")
	{
		for(int i = 0; i < 5; i++)
		{
			select[i] = true;
			if(i < 4)
			{
				if(slot[i].value == slot[i+1].value - 1)
				{
					select[i] = select[i+1] = false;
				}
			}
			if(i > 0)
			{
				if(slot[i].value == slot[i-1].value + 1)
				{
					select[i] = select[i+1] = false;
				}
			}
		}
		return;
	}
}

bool Hand::isSelected(int checkThis)
{
	return select[checkThis];
}

LPCWSTR Hand::Check()
{
	Card temp[5];

	int SecondNumbersInCommon = 0, 
		firstPairValue,
		secondPairValue;

	for(int i = 0; i < 5; ++i)
	{
		firstCardPair[i] = false;
		secondCardPair[i] = false;
	}

	bool useSecondPair = false;

	short HighCard;

	short HandType = 0; // 0 = single
						// 1 = Two of a kind 
						// 2 = Three of a kind
						// 3 = Four of a kind

	/////////////////////////////////////////////////////////////////////
	////					STRAIT   OR   STRAIT FLUSH                 //
	/////////////////////////////////////////////////////////////////////


	if(slot[0].value == slot[1].value - 1)
		if(slot[1].value == slot[2].value - 1)
			if(slot[2].value == slot[3].value - 1)
				if(slot[3].value == slot[4].value - 1)
				{
					high = slot[4].value;
					if(slot[0].suit == slot[1].suit)
						if(slot[1].suit == slot[2].suit)
							if(slot[2].suit == slot[3].suit)
								if(slot[3].suit == slot[4].suit)
								{
									if(slot[4].value == 14)
										return L"ROYAL FLUSH!";
									else
										return L"Strait Flush";
								}
								return L"Strait";
				}

	/////////////////////////////////////////////////////////////////////
	////					FLUSH                                      //
	/////////////////////////////////////////////////////////////////////

	if(slot[0].suit == slot[1].suit)
		if(slot[1].suit == slot[2].suit)
			if(slot[2].suit == slot[3].suit)
				if(slot[3].suit == slot[4].suit)
				{
					high = slot[4].value;
					return L"Flush";
				}

	


		/////////////////////////////////////////////////////////////////
		//    Check for double                                         //
		/////////////////////////////////////////////////////////////////


	for(int i = 0; i < 4 && HandType < 1; i++)
	{
		for(int j = i + 1; j < 5; j++)
		{
			if(slot[i].value == slot[j].value)
			{
				HighCard = slot[j].value;
				HandType++;
				firstPairValue = slot[j].value;
				firstCardPair[i] = firstCardPair[j] = true;
				break;
			}
		}
	}

	
	

	/////////////////////////////////////////////////////////////////
	//    Check for Triple                                        //
	/////////////////////////////////////////////////////////////////
	if(HandType == 1)
	{
		for(int i = 0; i < 5; i++)
		{
			if(!firstCardPair[i])
			{
				if(slot[i].value == firstPairValue)
				{
					HandType++;
					firstCardPair[i] = true;
					////////////////////////////
					//Check for four of a kind//
					////////////////////////////
					if(HandType == 3)
					{
						for(int j = 0; j < 5; j++)
						{
							if(firstCardPair[i])
							{
								high = slot[i].value;
								return L"Four of a Kind";
							}
						}
					}
				}
			}
		}
	}

	
	/////////////////////////////////////////////////////////////////////
	////					FULL HOUSE                                 //
	/////////////////////////////////////////////////////////////////////

	if(HandType == 1 || HandType == 2)
	{
		for(int i = 0; i < 5; i++)
		{
			if(!firstCardPair[i])
			{
				for(int j = 0; j < 5; ++j)
				{
					if(!firstCardPair[j] && j != i)
					{
						if(slot[i].value == slot[j].value)
						{
							secondCardPair[i] = secondCardPair[j] = true;
							secondPairValue = slot[i].value;
						}
					}
				}
			}
		}
		if(HandType == 1)
		{
			int count = 0;
			for(int i = 0; i < 5; i++)
			{
				if(!firstCardPair[i])
				{
					if(secondCardPair[i])
						count++;
				}
				if(count == 3)
				{
					high = secondPairValue;
					return L"Full House";
				}
			}
			if(count == 2)
			{
				if(secondPairValue > firstPairValue)
					high = secondPairValue;
				else
					high = firstPairValue;
				return L"Two Pair";
			}
			high = firstPairValue;
			return L"One Pair";
		}
		if(HandType == 2)
		{
			int count = 0;
			high = firstPairValue;
			for(int i = 0; i < 5; i++)
			{
				if(!firstCardPair[i])
				{
					if(secondCardPair[i])
					{
						return L"Full House";
					}
				}
			}
			return L"Three of a Kind";
		}
	}




	high = slot[4].value;
	return L"Junk";
}


















	////this function determines what kind of hand it is, i.e. full house or a three of a kind, etc.

	////types
	//int type[5] = {0};	//how many cards in the group
	//int	value[5] = {0};	//what the group has, like a group of 1's or 2's or J's etc.
	//int num = 1;	//how many different groups there are.

	////Sort the cards, counting the different types

	////Put the first card in it's own type
	//type[0] = 1;
	//value[0] = slot[0].value;

	////Put the other cards in sorted groups
	//for (int i=1; i < 5; i++)
	//{
	//	//get card and compare it to the cards before it until it hits the beginning or 
	//	bool stop = false;
	//	bool match = false;

	//	for (int j=0; j < i && !stop; j++)
	//	{
	//		//check if it's the same as any others before it
	//		if (slot[i].value == slot[j].value)
	//		{
	//			stop = true;
	//			match = true;
	//		}
	//	}

	//	//find the group

	//	if (match)
	//	{
	//		for (int k=0; k < 5; k++)
	//		{
	//			//put it in the group if it's the same value
	//			if(slot[i].value == value[k])
	//			{
	//				type[k]++;
	//			}
	//		}
	//	}

	//	//if none matched, put the card in a new group
	//	else
	//	{
	//		type[num]++;
	//		value[num] = slot[i].value;
	//		num++;
	//	}
	//}

	////find out what kind of hand it is based on the groups

	////five of a kind?
	//if (type[0] == 5)
	//	return L"Five of a Kind";

	////four of a kind?
	//else if (type[0] == 4 || type[1] == 4)
	//	return L"Four of a Kind";

	////full house?
	//else if (type[0] == 3 && type[1] == 2 || type[0] == 2 && type[1] == 3)
	//	return L"Full House";
	//
	////three of a kind?
	//else if (type[0] == 3 || type[1] == 3 || type[2] == 3)
	//	return L"Three of a Kind";

	////two pair?
	//else if (type[0] == 2 && type[1] == 2 || type[0] == 2 && type[2] == 2 || type[1] == 2 && type[2] == 2)
	//	return L"Two Pair";

	////one pair?
	//else if (type[0] == 2 || type[1] == 2 || type[2] == 2 || type[3] == 2)
	//	return L"One Pair";

	////if it's none of the above, then it's junk
	//return L"Junk";
